package org.enhance.common.helper;

import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.core.ResolvableType;
import org.springframework.core.env.Environment;

import java.util.Map;

/**
 * <p>
 * springboot2.x提供的属性绑定器
 * </p>
 *
 * @author wenpan 2022/12/10 1:34 下午
 */
public class PropertiesBinder2xHelper {

    private PropertiesBinder2xHelper() {
    }

    /**
     * <p>
     * 从 Map类型的properties 中按照prefix查找属性值并绑定到targetObj对象的对应属性上
     * properties 可以是自己从配置文件中读取的key-value键值对
     * </p>
     *
     * @param properties map
     * @param prefix     前缀
     * @param targetObj  目标对象
     * @author wenpan 2022/12/10 1:33 下午
     */
    public static <T> void bindDtpProperties(Map<?, Object> properties, String prefix, T targetObj) {
        ConfigurationPropertySource sources = new MapConfigurationPropertySource(properties);
        Binder binder = new Binder(sources);
        ResolvableType type = ResolvableType.forClass(targetObj.getClass());
        Bindable<?> target = Bindable.of(type).withExistingValue(targetObj);
        binder.bind(prefix, target);
    }

    /**
     * <p>
     * 从environment中按照prefix查找属性值并绑定到targetObj对象的对应属性上
     * </p>
     *
     * @param environment environment
     * @param prefix      前缀
     * @param targetObj   目标对象
     * @author wenpan 2022/12/10 1:32 下午
     */
    public static <T> void bindDtpProperties(Environment environment, String prefix, T targetObj) {
        Binder binder = Binder.get(environment);
        ResolvableType type = ResolvableType.forClass(targetObj.getClass());
        Bindable<?> target = Bindable.of(type).withExistingValue(targetObj);
        binder.bind(prefix, target);
    }
}